package db

import (
	"core/graylog"
	"core/rds"
	"core/utils"
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis"
	"time"
)

const (
	runLoopTime = time.Millisecond * 50
)

var runLoopBet int64 = 1   // 调节速度
var runLoopCount int64 = 1 // 循环总数

func makeSyncKey() string {
	return "sync-list"
}

func RunSyncLoop() {
	tick := time.NewTicker(runLoopTime)
	for {
		select {
		case <-tick.C:
			runLoopCount++
			go SaveOneToMysql()
		}
	}
}

func SaveOneToMysql() {
	if runLoopCount%runLoopBet != 0 {
		return
	}
	var err error
	defer utils.CatchPanicAndErr("SaveOneToMysql", &err, graylog.M{"runLoopCount": runLoopCount, "runLoopBet": runLoopBet})
	client := rds.GetSyncClient()
	key := makeSyncKey()
	content, err := client.RPop(key).Result()
	if err == redis.Nil {
		if runLoopBet < 128 {
			runLoopBet *= 2
		}
		err = nil
		utils.Info(runLoopCount, runLoopBet)
		return
	} else if err != nil {
		return
	}
	if runLoopBet > 1 {
		runLoopBet /= 2
	}
	if runLoopCount > 0xffffffff {
		runLoopCount = 0
	}

	conf, err := DecodeModel(content)
	if err != nil {
		return
	}
	err = conf.Model.SaveToMysql(conf.UID)
	if err != nil {
		return
	}
	graylog.Info("sync成功", graylog.M{
		"key":      conf.Key,
		"playerId": conf.UID,
		"values":   fmt.Sprintf("%v", conf.Values),
	})
	return
}

// 同步到mysql的列表，添加一项
func PushToSyncList(conf *ModelData) (err error) {
	utils.Info("PushToSyncList", conf)
	content, err := json.Marshal(*conf)
	if err != nil {
		utils.Error(err)
		return
	}
	client := rds.GetSyncClient()
	key := makeSyncKey()
	err = client.LPush(key, string(content)).Err()
	if err != nil {
		utils.Error(err)
		return
	}
	return
}
